package controller

import (
	"math/rand"
	"strings"
	"time"

	. "gddgame.cc/galaxy/common/dsl/game"
	. "gddgame.cc/galaxy/common/dsl/game/item"
	. "gddgame.cc/galaxy/common/dsl/game/reward"
	. "gddgame.cc/galaxy/common/dsl/game/task"
	. "gddgame.cc/galaxy/common/dsl/web"
	"gddgame.cc/galaxy/project/star/star/model"
	"gddgame.cc/galaxy/utils"
	"gddgame.cc/galaxy/utils/def"
)

func ReceiveRewardMessage(context def.Context, user *model.User, messageId int, items map[int]*Item, lang string) (*Reward, error) {
	message, err := Center.GetMessage(user.Id, messageId)
	if err != nil {
		return nil, err
	}
	_ = Center.ReadMessage(user.Id, messageId)
	data := map[string]interface{}{}
	if err := ReceiveReward(context, user, &message.Reward, data); err != nil {
		return nil, err
	}
	if err := Center.GetUserStats(context, user, Center.StatData); err != nil {
		return nil, err
	}
	if err := Center.UpdateUser(user, data); err != nil {
		return nil, err
	}
	message.Reward.BindInfo(items, lang)
	return &message.Reward, nil
}

func AddZoneTasks(context def.Context, node string, tasks []int, level int) ([]*GameTask, error) {
	GameTaskModel, err := Env.GetModel(GameTaskName)
	if err != nil {
		return nil, err
	}
	// 将前一次任务过期
	if _, err := GameTaskModel.Query().Where("null", "expire_time", nil).Where("=", "target_id", node).Update(map[string]interface{}{
		"expire_time": time.Now(),
	}); err != nil {
		return nil, SystemExceptionDetail("更新任务失败", err)
	}
	now := time.Now()
	taskList := make([]*GameTask, len(tasks))
	for index := range tasks {
		inside := model.TaskInside{
			Targets: []int{},
			Objects: []int{},
		}
		id := tasks[index]
		task := Center.Tasks[id]
		taskLogic := &task.Logic
		names := map[string]string{}
		descs := map[string]string{}
		// 安固定怪物还是分组怪物设定
		var target map[string]string
		var targetKey string

		// 随机怪物
		if taskLogic.Targets != nil && len(taskLogic.Targets) > 0 {
			targets := RandomContent(taskLogic.Targets, Center.TargetGroup, taskLogic.All)
			// 获取bosskey
			if taskLogic.Boss {
				for _, key := range targets {
					if actor, ok := Center.Targets[key]; ok {
						if actor.IsBoss {
							inside.Boss = key
						}
					}
				}
			}
			for _, key := range targets {
				if actor, ok := Center.Targets[key]; ok {
					if actor.IsBoss {
						continue
					}
					inside.Targets = append(inside.Targets, key)
				}
			}
			// 使用第一个分组作为名称
			group := Center.Groups[taskLogic.Targets[0]]
			targetKey = group.StatKey
			target = group.Name
			if len(targets) == 1 {
				key := targets[0]
				actor := Center.Targets[key]
				target = actor.Name
			}
		}

		// 随机场景道具
		if taskLogic.Objects != nil && len(taskLogic.Objects) > 0 {
			inside.Objects = RandomContent(taskLogic.Objects, Center.ObjectGroup, taskLogic.All)

			l := rand.Int31n(int32(len(taskLogic.Objects)))
			group := Center.Groups[taskLogic.Objects[int(l)]]
			targetKey = group.StatKey
			target = group.Name
			if len(inside.Objects) == 1 {
				key := inside.Objects[0]
				actor := Center.ObjectMap[key]
				target = actor.Name
			}
		}

		// 随机目标值
		targetNum := rand.Int31n(int32(taskLogic.MaxNumber-taskLogic.MinNumber+1)) + taskLogic.MinNumber
		// 添加一个boss
		if taskLogic.Boss {
			targetNum += 1
		}
		// 根据怪物选择，生成合适的任务名称
		for key, n := range task.Name {
			names[key] = strings.Replace(strings.Replace(n, `{target}`, target[key], 1), `{number}`, string(targetNum), 1)
		}
		for key, n := range task.Desc {
			names[key] = strings.Replace(strings.Replace(n, `{target}`, target[key], 1), `{number}`, utils.ToString(targetNum), 1)
		}
		var factors []Factor
		if task.Type == model.ZoneAdditionTask {
			factors = []Factor{{Source: PlaybookSource, Key: targetKey, Value: targetNum}}
		} else if task.Type == model.ZoneTask {
			factors = []Factor{{Source: PlaybookSource, Key: targetKey, Value: targetNum}}
		}

		// 困难度 * 战区等级 = 最高难度百分比
		//fmt.Println(task.Difficult, level, model.ZonePowerList, task.Difficult*(level+1)*100/(len(model.ZonePowerList)*center.MaxZoneTaskDifficult))
		rewardLogic := GenerateLogic(Env, task.Difficult*(level+1)*100/(len(model.ZonePowerList)*Center.MaxZoneTaskDifficult), Center.MaxItemLevel, task.RewardType)

		rewardLogic.AddItems(Center.ItemMap)
		// todo 道具奖励
		// 随机任务奖励
		reward := Reward{}
		GenerateReward(Env, rewardLogic, &reward, Center.ItemMap)
		gameTask := GameTask{
			Name:       names,
			Desc:       descs,
			Type:       task.Type,
			Difficult:  task.Difficult,
			IsAddUp:    task.IsAddUp,
			TargetId:   node,
			Factors:    factors,
			StartTime:  &now,
			ExpireTime: nil,
			Reward:     reward,
			Inside:     inside,
		}
		if _, err := GameTaskModel.Insert(&gameTask); err != nil {
			return nil, SystemExceptionDetail("添加任务失败", err)
		}
		taskList[index] = &gameTask
	}

	return taskList, nil
}

func RandomContent(source []int, groups map[int][]int, all bool) (targets []int) {
	tmp := []int{}
	selected := []int{}
	for _, key := range source {
		// 求所有选择的交集
		if keys, ok := groups[key]; ok {
			if len(selected) > 0 {
				for _, v := range selected {
					for _, vv := range keys {
						if vv == v {
							tmp = append(tmp, vv)
						}
					}
				}
				selected = tmp
				tmp = tmp[:0]
			} else {
				selected = keys
			}
		}
	}
	if all {
		targets = selected
	} else {
		for i := 0; i < len(source); i++ {
			l := rand.Int31n(int32(len(selected)))
			targets = append(targets, selected[l])
		}
	}

	return
}
